﻿using AutoMapper;

using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;

using Models;

using RESTfulDemo.Dtos;
using RESTfulDemo.Services;

namespace RESTfulDemo.Controllers {

    [Route("api/infos")]
    public class RESTfulDemo : ControllerBase {
        private readonly IService mStudentService;
        private readonly IMapper mMapper;

        public RESTfulDemo(IService studentService, IMapper mapper) {
            mStudentService = studentService;
            mMapper = mapper;
        }

        [HttpGet]
        public async Task<IActionResult> GetInfos() {
            var datas = await mStudentService.GetStudentInfosAsync();
            if (datas == null || datas.Count() == 0) {
                return BadRequest(datas);
            }
            return Ok(datas);
        }

        [HttpGet("{id}", Name = "GetInfoById")]
        public async Task<IActionResult> GetInfoById([FromRoute] Guid id) {

            if (!await mStudentService.StudentExistAsync(id)) {
                return NotFound("未找到该学员 => " + id);
            }

            var studentInfo = await mStudentService.GetStudentInfoByIdAsync(id);

            var studentInfoDto = mMapper.Map<StudentInfoDto>(studentInfo);

            return Ok(studentInfoDto);
        }

        [HttpPost]
        public async Task<IActionResult> CreateInfo([FromBody] StudentInfoDto studentInfoDto) {
            var info = mMapper.Map<StudentInfo>(studentInfoDto);

            await mStudentService.AddStudentInfoAsync(info);

            //自动生成需要重定向的URL
            return CreatedAtRoute("GetInfoById", new { id = info.Guid }, studentInfoDto);

            //用户自定义需要将页面重定向到的URL
            //return Created("GetInfoById", studentInfoDto);
        }

        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteInfo([FromRoute] Guid id) {

            if (!await mStudentService.StudentExistAsync(id)) {
                return NotFound("未找到该学员 => " + id);
            }

            await mStudentService.DeleteStudentInfoAsync(id);
            return NoContent();
        }

        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateInfo(
            [FromRoute] Guid id,
            [FromBody] StudentInfoUpdateDto studentInfoDto
            ) {

            if (!await mStudentService.StudentExistAsync(id)) {
                return NotFound("未找到该学员 => " + id);
            }

            var infoToRoute = await mStudentService.GetStudentInfoByIdAsync(id);

            //将 studentInfoDto 数据映射到 infoToRoute
            mMapper.Map(studentInfoDto, infoToRoute);

            await mStudentService.UpdateStudentInfoAsync(infoToRoute);

            return Ok(studentInfoDto);
        }

        [HttpPatch("{id}")]
        public async Task<IActionResult> PartiallyUpdateInfo(
            [FromRoute] Guid id,
            [FromBody] JsonPatchDocument<StudentInfoUpdateDto> patchDocument
            ) {

            if (!await mStudentService.StudentExistAsync(id)) {
                return NotFound("未找到该学员 => " + id);
            }

            var infoFromRepo = await mStudentService.GetStudentInfoByIdAsync(id);

            var infoDto = mMapper.Map<StudentInfoUpdateDto>(infoFromRepo);

            //将传入的数据应用到infoDto上
            patchDocument.ApplyTo(infoDto, ModelState);

            if (!TryValidateModel(infoDto)) {
                return ValidationProblem(ModelState);
            }

            mMapper.Map(infoDto, infoFromRepo);

            await mStudentService.UpdateStudentInfoAsync(infoFromRepo);


            return Ok(infoDto);
        }
    }
}